using System;
using System.Data;
//using System.Data.SQL;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using  System.Text.RegularExpressions ;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
namespace CStock
{
	/// <summary>
	/// Summary description for WebQuotes.
	/// </summary>
	public class WebQuotes
	{

		public WebQuotes()
		{
			
		}
        
        protected static DateTime CreateDataNow()
        {
            DateTime dt = DateTime.Today;
            string year, month, day;//, high = "-", low  = "-", cassa = "-", wknv;
            year = dt.Year.ToString();
            month = dt.Month.ToString();
            day = dt.Day.ToString();
            return dt;
        }
        /// <summary>
        /// GetYahoo_Intraday
        /// </summary>
        /// <param name="dc"></param>
        /// <returns></returns>
     
      
  
        protected static void AdjustMatches(string strcurrentValue, RegExStructuresYahooIndexData regExStruct, string strchange, string name,
            out double currentValue, out double change)
        {
            strcurrentValue = strcurrentValue.Remove(strcurrentValue.Length - 3, 3);

            currentValue = 0f;
            change = 0f;
            MatchCollection matcheChangePercent = Regex.Matches(strchange, @regExStruct.ChangeInPercent);
            if (matcheChangePercent.Count > 0)
            {
                strchange = matcheChangePercent[0].Result("${1}");
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Error matching values for " + name + "; " + strchange);
            }
            try
            {
                currentValue = Convert.ToDouble(strcurrentValue, CUtil.Conversions.CultureGerman);
                change = Convert.ToDouble(strchange, CUtil.Conversions.CultureGerman);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Error in converting values for " + name + "; to convert: " + strcurrentValue + "; " + strchange);
            }
        }
        protected static bool InterpretMatches(int i, RegExStructuresYahooIndexData regExStruct, 
            MatchCollection matchesBlocks, IPortfolio portf)
        {
            string name;
            string strcurrentValue;
            double currentValue;
            double change;
            string strchange;
            string symbol = string.Empty;

            string block = matchesBlocks[i].Result("${1}");
            MatchCollection matchesNames = Regex.Matches(block, @regExStruct.IndexName);
            MatchCollection matchesDetails = Regex.Matches(block, @regExStruct.IndexDetails);
            int indexDetails = -3;
            for (int j = 0; j < matchesNames.Count; j++)
            {
                indexDetails += 4;
                change = 0f;
                currentValue = 0f;

                name = matchesNames[j].Result("${1}");

                if (indexDetails >= matchesDetails.Count)
                {
                    System.Windows.Forms.MessageBox.Show("Internet page cannot be interpreted - for share " + name);
                    symbol = name;
                    strchange = matchesBlocks[0].Result("${1}");
                    break;
                }
                else
                {
                    symbol = matchesDetails[indexDetails].Result("${1}");
                    strcurrentValue = matchesDetails[indexDetails + 1].Result("${1}");
                    strchange = matchesDetails[indexDetails + 2].Result("${1}");
                    //remove the last 3 values (for the german website - error in yahoo for values
                    AdjustMatches(strcurrentValue, regExStruct, strchange, name,
                        out currentValue, out change);


                }

                AddDataItemToPortfolio(portf, name, symbol, currentValue, change);

            }
            return true;

        }

        protected static bool AddDataItemToPortfolio(IPortfolio portf, string name, string symbol, double currentValue, double change)
        {

            name = WebDownload.ReplaceInvalidCharacters(name);

            IDataItem di = new DataItem();
            di.Parent = portf;
            di.DataClass = new DataClassDaily();
            di.DataClass.ID = name;
            di.DataClass.Parent = di;
            IQuote qu = new Quote();
            qu.CLOSEc = currentValue;
            qu.Change = change;
            qu.DATE = DateTime.Now;
            di.Symbol = symbol;
            di.ID = name;
            di.DataClass.QuoteCollection.Add(qu);
            try
            {
                di.DataClass.Serialize();
                di.Serialize();
            }
            catch (Exception ex2)
            {
                Debug.Assert(false, "Error serializing data for " + name + "; " + ex2.Message);
            }
            portf.DataItems.Items.Add(di);
            return true;

        }
     
        protected static bool GetNameAndSymbol(Match m, RegExStructuresYahooStockSymbols_DE regExStruct,
            out string name, out string symbol)
        {

            name = string.Empty;
            symbol = string.Empty;

            string strStockLine = m.Result("${1}");
            Regex regexSymbol = new Regex(@regExStruct.Symbol);
            if (!regexSymbol.IsMatch(strStockLine))
            {
                Debug.Assert(false, "Symbol not found for line " + strStockLine);
            }
            else
            {
                symbol = regexSymbol.Match(strStockLine).Result("${1}");

                Regex regexName = new Regex(@regExStruct.Name);
                if (!regexName.IsMatch(strStockLine))
                {
                    regexName = new Regex(@regExStruct.NameCheck);
                    if (!regexName.IsMatch(strStockLine))
                    {
                        System.Windows.Forms.MessageBox.Show("Did not find name for symbol : " + symbol + "; from: " + strStockLine);
                        name = symbol;
                        //Debug.Assert(false, "Name not found for symbol " + portf.ID + "; share: " + symbol);
                    }
                    else
                    {
                        name = regexName.Match(strStockLine).Result("${1}");
                    }
                }
                else
                {
                    name = regexName.Match(strStockLine).Result("${1}");
                }
            }
            if (String.IsNullOrEmpty(name))
            {
                System.Windows.Forms.MessageBox.Show("Could not load name for symbol : " + symbol);
                name = symbol;
                //Debug.Assert(false, "Name of share cannot be empty " + symbol);

            }
            name = WebDownload.ReplaceInvalidCharacters(name);
            return true;

        }
       
     
        
   
		
  
        

        #region helpers


        protected static IList<string> MatchTableLines_FinancialData(string text, string matchTableLine)
        {
            IList<string> tableLines = new List<string>();

            //worked: string matchTableLine = @"<TD ALIGN=LEFT NOWRAP WIDTH=6. >(?<1>.*)</TD>";
            //worked : 19 times (instead of 20): string matchTableLine = @"<TD ALIGN=LEFT NOWRAP WIDTH=6% >(?<1>.*?)<TR ALIGN=";
            

            MatchCollection matchesTableLines = Regex.Matches(text, matchTableLine);
            for (int j = 0; j < matchesTableLines.Count; j++)
            {
                //gets a line like
                //12.2009<.TD>\r\n<TD ALIGN=RIGHT NOWRAP WIDTH=18% >26,30<.TD>\r\n<TD ALIGN=RIGHT NOWRAP WIDTH=18% >1,48<.TD>\r\n<TD ALIGN=RIGHT NOWRAP WIDTH=18% >2,45<.TD>\r\n<TD ALIGN=RIGHT NOWRAP WIDTH=18% >4,4<.TD>\r\n<.TR>\r\n"
                string tableLine = matchesTableLines[j].Result("${1}");
                tableLines.Add(tableLine);

            }
            return tableLines;
        }
        protected static IList<string> MatchFinancialDataValues(string tableLine, string matchValue)
        {
            IList<string> dataValues = new List<string>();
            MatchCollection matchesData = Regex.Matches(tableLine, matchValue, RegexOptions.Singleline);
            for (int k = 0; k < matchesData.Count; k++)
            {
                string value = matchesData[k].Result("${1}");
                dataValues.Add(value);
            }
            return dataValues;
        }
        protected static double MatchMSNNegativeValue(string valRead)
        {
            //string matchNegativeValue = @"=..s5..>(?<1>.*)<.span><.TD";
            //string matchNegativeValue = @"=..s5..>(?<1>.*)<.span>";
            string matchNegativeValue = @">(?<1>.*)<";


            double valNegative = -1;
            MatchCollection matchValues = Regex.Matches(valRead, matchNegativeValue);
            if (matchValues.Count > 0)
            {
                valNegative = Convert.ToDouble(matchValues[0].Result("${1}"), CUtil.Conversions.CultureGerman);
            }
            else
            {
                Debug.Assert(false, "Could not get negative value for html text: " + valRead);
            }

            return valNegative;

        }
        protected static DateTime GetDateFromMSNString_1(string stringDate)
        {
            string[] arrStr = stringDate.Split(new Char[] { '.' }, 100);
            DateTime dt = new DateTime(Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[0]), 1);

            return dt;
        }
        protected static DateTime GetDateFromMSNString_2(string stringDate)
        {
            string[] arrStr = stringDate.Split(new Char[] { '.' }, 100);
            DateTime dt = new DateTime(Convert.ToInt32("20" + arrStr[1]), Convert.ToInt32(arrStr[0]), 1);

            return dt;
        }
        protected static DateTime GetDateFromMSNString_3(string stringDate)
        {
            string[] arrStr = stringDate.Split(new Char[] { ' ' }, 100);
            string quartal = arrStr[1];
            DateTime dt = new DateTime(1900,1,1);
            switch (quartal)
            {
                case "Q1":
                    {
                        dt = new DateTime(Convert.ToInt32(arrStr[0]), 4, 1);
                        break;
                    }
                case "Q2":
                    {
                        dt = new DateTime(Convert.ToInt32(arrStr[0]), 7, 1);
                        break;
                    }
                case "Q3":
                    {
                        dt = new DateTime(Convert.ToInt32(arrStr[0]), 10, 1);
                        break;
                    }
                case "Q4":
                    {
                        dt = new DateTime(Convert.ToInt32(arrStr[0]), 12, 31);
                        break;
                    }

            }

            return dt;
            
        }
        protected static long GetMSNInt(string strRead, System.Globalization.CultureInfo culture)
        {
            long lval = 0;
            try
            {
                double dVal = 0;
                

                string[] arrStr = strRead.Split(new Char[] { ' ' }, 100);
                if (arrStr.GetLength(0) > 0)
                {
                    try
                    {
                        dVal = Convert.ToDouble(arrStr[0], culture);
                    }
                    catch (Exception err)
                    {
                        Debug.WriteLine("Could not convert string to double " + strRead + "; " + err.Message);
                        dVal = 0;
                    }
                    if (arrStr[1] == "Mil")
                    {
                        lval = Convert.ToInt64(dVal * 1000000);

                    }
                }

            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in converting integer: " + strRead +"; Errir is: " + err.Message);
            }
            return lval;
        }
        protected static double ConvertMSNValue(string strRead, System.Globalization.CultureInfo culture)
        {
            double dVal = 0;
            try
            {
                
                if (strRead.Contains("span"))
                {
                    dVal = MatchMSNNegativeValue(strRead);
                    return dVal;
                }

                try
                {
                    dVal = Convert.ToDouble(strRead, culture);
                }
                catch(Exception err)
                {
                    Debug.WriteLine("Could not convert string to double " + strRead + "; " + err.Message);
                    
                    dVal = 0;
                }


                return dVal;
            }
            catch
            {
                return dVal;
            }
        }
        #endregion



        //protected static string extractMatchValue(string line)
        //{
        //    string matchTableLine = @">(?<1>.*?)<";
        //    MatchCollection matches = Regex.Matches(retPage,quoteSearch);
        //    try
        //    {
        //        Match m = matches[0];
        //        quoteResult = m.ToString();

        //        if (regex.IsMatch(retPage))
        //        {
        //            quoteResult = regex.Match(retPage).Result("${1}");		

        //    time = regex.Match(retPage).Result("${1}");

        //}
        protected static void RemoveOneTable(IList<string> listRead)
        {
            for (int i = 0; i < listRead.Count; i++)
            {
                if (!listRead[0].Contains(@"</TR></TABLE>"))
                {
                    listRead.RemoveAt(0);
                }
                else
                {
                    break;
                }
            }
            listRead.RemoveAt(0);
        }
       
        protected static bool ExtractFirstTable_1(IList<string> listRead, IDataItem dataItem)
        {
            try
            {
                RemoveOneTable(listRead);
                //two additional removes


                int iterationValue = -1;
                IFundamentalData fd = null;
                for (int i = 0; i < listRead.Count; i++)
                {
                    if(listRead[i].Contains(@"</TABLE>"))
                    {
                        RemoveOneTable(listRead);
                        break;

                    }
                    else if (!listRead[i].Contains(@"</TR>"))
                    {
                        listRead[i] = listRead[i].Replace("><", string.Empty);
                        string matchValue = @">(?<1>.*?)<";
                        string tableLine = listRead[i];
                        IList<string> resultValues = MatchFinancialDataValues(tableLine, matchValue);
                        iterationValue++;
                        switch (iterationValue)
                        {
                            case 0:
                                {

                                    fd = GetFundamentalDataInstance_1(resultValues[0], dataItem, dataItem.FundamentalData);
                                    break;
                                }
                            case 1:
                                {
                                    if (fd != null)
                                    {
                                        fd.PE = ConvertMSNValue(resultValues[0], CUtil.Conversions.CultureGerman);
                                    }
                                    break;
                                }
                            case 2:
                                {
                                    if (fd != null)
                                    {
                                        fd.PricePerSales = ConvertMSNValue(resultValues[0], CUtil.Conversions.CultureGerman);
                                    }
                                    break;

                                }
                            case 3:
                                {
                                    if (fd != null)
                                    {
                                        fd.PricePerBook = ConvertMSNValue(resultValues[0], CUtil.Conversions.CultureGerman);
                                    }
                                    break;
                                }
                        }



                    }
                    else
                    {
                        iterationValue = -1;
                        fd = null;
                    }


                }



                return true;
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in ExtractList : " + err.Message);
                return false;

            }

        }
        protected static bool ExtractSecondTable_1(IList<string> listRead, IDataItem dataItem)
        {
            try
            {
               
                int iterationValue = -1;
                IFundamentalData fd = null;
                for (int i = 0; i < listRead.Count; i++)
                {
                    if (listRead[i].Contains(@"</TABLE>"))
                    {
                        //RemoveOneTable(listRead);
                        break;

                    }
                    else if (!listRead[i].Contains(@"</TR>"))
                    {
                        listRead[i] = listRead[i].Replace("><", string.Empty);
                        string matchValue = @">(?<1>.*?)<";
                        string tableLine = listRead[i];
                        IList<string> resultValues = MatchFinancialDataValues(tableLine, matchValue);
                        iterationValue++;
                        switch (iterationValue)
                        {
                            case 0:
                                {
                                    fd = GetFundamentalDataInstance_1(resultValues[0], dataItem, dataItem.FundamentalData);
                                    break;
                                }
                            case 1:
                                {
                                    if (fd != null)
                                    {
                                        fd.BVPS = ConvertMSNValue(resultValues[0], CUtil.Conversions.CultureAmerican);
                                    }
                                    break;
                                }
                      
                            case 3:
                                {
                                    if (fd != null)
                                    {
                                        fd.ROIC = ConvertMSNValue(resultValues[0], CUtil.Conversions.CultureAmerican);
                                    }
                                    break;
                                }
                        }



                    }
                    else
                    {
                        iterationValue = -1;
                        fd = null;
                    }


                }



                return true;
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in ExtractList : " + err.Message);
                return false;

            }

        }
        protected static bool GetMSN_FundamentalData_FirstPart(IDataItem dataItem)
        {
            
            string symbol; string region;
            CUtil.IOUtil.SplitSymbolAndRegion(dataItem.Symbol, out symbol, out region);


            string url = @"http://de.moneycentral.msn.com/investor/invsub/results/compare.asp?Page=TenYearSummary&Symbol=" + region + ":" + symbol;
            
            IList<string> listRead = WebClientFeed.ReadPage_ToList(url);
            if (listRead != null && listRead.Count > 0)
            {
                if (ExtractFirstTable_1(listRead, dataItem))
                {
                    if ( ExtractSecondTable_1(listRead, dataItem))
                        return true;
                }
            }
            
            return false;


        }
        protected static string GetInternetPageForFundamentalData_1(IDataItem dataItem)
        {
            //dataItem.Symbol = "BAYN.DE";
            string symbol; string region;
            CUtil.IOUtil.SplitSymbolAndRegion(dataItem.Symbol, out symbol, out region);

            string url = @"http://de.moneycentral.msn.com/investor/invsub/results/compare.asp?Page=TenYearSummary&Symbol=" + region + ":" + symbol;
           
           
            //---------------------
            string strReturn = WebClientFeed.GetInternetPage(url);
            
            if (strReturn != null || strReturn != string.Empty)
            {
                strReturn = WebDownload.ReplaceInvalidCharacters(strReturn);
            }
            return strReturn;
        }
        protected static string GetInternetPageForFundamentalData_2(IDataItem dataItem)
        {
            
            string symbol; string region;
            CUtil.IOUtil.SplitSymbolAndRegion(dataItem.Symbol, out symbol, out region);

        
            string url = @"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=" + region + "%3a" + symbol + "&lstStatement=10YearSummary&stmtView=Ann";
            //string strReturn = SocketDownload.GetInternetPage(url);
            
            //Debug.Assert(strReturn != string.Empty, "No page got for : " + url);
            //if (strReturn != null || strReturn != string.Empty)
            //{
            //    strReturn = ReplaceInvalidCharacters(strReturn);
            //}
            //return strReturn;

            string strReturn = WebClientFeed.GetInternetPage(url);

            if (strReturn != null || strReturn != string.Empty)
            {
                strReturn = WebDownload.ReplaceInvalidCharacters(strReturn);
            }
            return strReturn;
            
        }

        public static bool GetMSN_FundamentalData(IDataItem dataItem)
        {
            
           
            if (GetMSN_FundamentalData_FirstPart(dataItem))
            {
                if (GetMSN_FundamentalData_SecondPart(dataItem))
                {
                    return true;
                }

            }

            return false;
        }
        protected static void ExtractFirstPartFromLine(string tableLine,string matchValue, IDataItem dataItem)
        {
            IList<string> values = MatchFinancialDataValues(tableLine, matchValue);
            if (values.Count == 5)
            {
                string dataString = values[0];
                IFundamentalData fd = GetFundamentalDataInstance_1(values[0], dataItem, dataItem.FundamentalData);

                fd.PE = ConvertMSNValue(values[1], CUtil.Conversions.CultureGerman);
                fd.PricePerSales = ConvertMSNValue(values[2], CUtil.Conversions.CultureGerman);
                fd.PricePerBook = ConvertMSNValue(values[3], CUtil.Conversions.CultureGerman);

            }
            else
            {
                string dataString = values[0];
                IFundamentalData fd = GetFundamentalDataInstance_1(values[0], dataItem, dataItem.FundamentalData);

                fd.BVPS = ConvertMSNValue(values[1], CUtil.Conversions.CultureAmerican);
                fd.ROIC = ConvertMSNValue(values[3], CUtil.Conversions.CultureAmerican);


            }
        }
        /// <summary>
        /// gets from page
        ///http://de.moneycentral.msn.com/investor/invsub/results/compare.asp?Page=TenYearSummary&Symbol=DE%3aBAYN
        ///data
        ///PE 
        ///PricePerSales 
        ///PricePerBook 
        ///BVPS 
        ///ROIC 
        /// </summary>
        /// <param name="dataItem"></param>
        private static bool GetMSN_FundamentalData_FirstPart_OldMethod(IDataItem dataItem)
        {
            try
            {
                string strReturn = GetInternetPageForFundamentalData_1(dataItem);
                if (strReturn == null || strReturn == string.Empty)
                    return false;

                //string matchTableLine = @"<TD ALIGN=LEFT NOWRAP WIDTH=6(?<1>.*?)<TR ALIGN=";
                string matchTableLine = @"TD.ALIGN=LEFT.NOWRAP.WIDTH=6(?<1>.*?)<TR.ALIGN=";
                
                IList<string> tableLines = MatchTableLines_FinancialData(strReturn, matchTableLine);

                if (tableLines.Count > 0)
                {
                    
                    for (int i = 0; i < tableLines.Count; i++)
                    {
                        string matchValue = @"% >(?<1>.*?)<.TD";
                        string tableLine = tableLines[i];
                        ExtractFirstPartFromLine(tableLine, matchValue, dataItem);
                        
                        
                    }
                }
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in GetMSN_FundamentalData: " + err.Message);
                return false;
            }
            return true;
        }
        protected static IFundamentalData GetFundamentalDataInstance(DateTime dt, IDataItem dataItem, List<IFundamentalData> listFundamentalData)
        {

            IFundamentalData fd = FundamentalData.GetItemFromListPerDate(dt, listFundamentalData);
            if (fd == null)
            {
                fd = new FundamentalData(dataItem.ID);
                fd.Date = dt;
                //add at the right place so that it gets sorted
                for (int i = 0; i < listFundamentalData.Count; i++)
                {
                    IFundamentalData fdCheck = listFundamentalData[i];
                    if (fd.Date.Year > fdCheck.Date.Year)
                    {
                        listFundamentalData.Insert(i, fd);
                        break;
                    }
                }

               

            }
            return fd;

        }
        protected static IFundamentalData GetFundamentalDataInstance_1(string dateString, IDataItem dataItem, List<IFundamentalData> listFundamentalData)
        {
            
            DateTime dt = GetDateFromMSNString_1(dateString);
            return GetFundamentalDataInstance(dt, dataItem, listFundamentalData);

        }
        protected static IFundamentalData GetFundamentalDataInstance_2(string dateString, IDataItem dataItem, List<IFundamentalData> listFundamentalData)
        {
            DateTime dt = GetDateFromMSNString_2(dateString);
            return GetFundamentalDataInstance(dt, dataItem, listFundamentalData);
        }
        protected static bool ExtractSecondPartFromLine(string tableLine, string matchValue, IDataItem dataItem, ref int indexSecondTable, int i)
        {
            try
            {

                IList<string> values = MatchFinancialDataValues(tableLine, matchValue);
                IFundamentalData fd = null;

                if (values.Count > 0)
                {
                    if (values[1] == "Current Assets")
                    {
                        indexSecondTable = i;
                        //stop first round
                    }
                    //first table
                    else if (indexSecondTable < 0)
                    {
                        fd = GetFundamentalDataInstance_2(values[0], dataItem, dataItem.FundamentalData);
                        fd.Sales = ConvertMSNValue(values[1], CUtil.Conversions.CultureAmerican);
                        fd.EBIT = ConvertMSNValue(values[2], CUtil.Conversions.CultureAmerican);
                        fd.Depreciations = ConvertMSNValue(values[3], CUtil.Conversions.CultureAmerican);
                        fd.IncomeNet = ConvertMSNValue(values[4], CUtil.Conversions.CultureAmerican);
                        fd.EPS = ConvertMSNValue(values[5], CUtil.Conversions.CultureAmerican);
                        fd.TaxRate = ConvertMSNValue(values[6], CUtil.Conversions.CultureAmerican);

                    }
                    else
                    //second table
                    {
                        fd = GetFundamentalDataInstance_2(values[0], dataItem, dataItem.FundamentalData);
                        fd.Assets = ConvertMSNValue(values[1], CUtil.Conversions.CultureAmerican);
                        fd.LiabilitiesAll = ConvertMSNValue(values[2], CUtil.Conversions.CultureAmerican);
                        fd.NoShares = GetMSNInt(values[4], CUtil.Conversions.CultureAmerican);

                    }
                }
                return true;
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in ExtractSecondPartFromLine: " + err.Message);
                return false;
            }
        }
        private static bool GetMSN_FundamentalData_SecondPart(IDataItem dataItem)
        {
            try
            {
                string strReturn = GetInternetPageForFundamentalData_2(dataItem);
                if (strReturn == null || strReturn == string.Empty)
                    return false;
               
                string matchTableLine = @"padding-right:5px;vertical-align:bottom.(?<1>.*?).td><.tr>";
                

                IList<string> tableLines = MatchTableLines_FinancialData(strReturn, matchTableLine);

                int indexSecondTable = -1;
                if (tableLines.Count > 0)
                {
                    for (int i = 1; i < tableLines.Count; i++)
                    {
                        tableLines[i] = tableLines[i].Replace("><", string.Empty);
                        string matchValue = @">(?<1>.*?)<";
                        string tableLine = tableLines[i];
                        
                        ExtractSecondPartFromLine(tableLine, matchValue, dataItem, ref indexSecondTable, i);

                    }
                }
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in GetMSN_FundamentalData: " + err.Message);
                return false;
            }
            return true;
        }
      

        private static string GetLineMatch(string tableLine, string matchValue)
        {
            MatchCollection matchesData = Regex.Matches(tableLine, matchValue, RegexOptions.Singleline);
            string value = string.Empty;
            if(matchesData.Count > 0)
                value = matchesData[0].Result("${0}");

            return value;
        }
   
       
        private static void CreateQuartalInstances(string line, IDataItem dataItem)
        {
            string matchLine = @">(?<1>.*?)<.td>";
            IList<string> tableLines = MatchTableLines_FinancialData(line, matchLine);
            
           
            for (int i = 0; i < tableLines.Count; i++)
            {
                string dateString = tableLines[i];
                DateTime dt = GetDateFromMSNString_3(dateString);
                GetFundamentalDataInstance(dt, dataItem, dataItem.FundamentalData_Quartals);
                               
            }
        }
        private static IList<double> ExtractListOfDoubles(string line, IDataItem dataItem)
        {
            IList<double> listDoubles = new List<double>();
            //IList<string> tableLines;
            string matchLine = @">(?<1>.*?)<.td>";
            IList<string> tableLines = MatchTableLines_FinancialData(line, matchLine);

            for (int i = 0; i < dataItem.FundamentalData_Quartals.Count; i++)
            {
                if (i == 0)
                {
                    //string matchAgain = @"right..>(?<1>.*?)<.td>";
                    //IList<string> tableLinesFirst = MatchTableLines_FinancialData(tableLines[0], matchAgain);
                    string strFirstValue = tableLines[0];
                    int indexCut = strFirstValue.IndexOf(".>", 0);
                    {
                        strFirstValue = strFirstValue.Remove(0, indexCut + 2);
                    }
                    listDoubles.Add(ConvertMSNValue(strFirstValue, CUtil.Conversions.CultureAmerican));
                }
                else
                {
                     listDoubles.Add(dataItem.FundamentalData_Quartals[i].Sales = ConvertMSNValue(tableLines[i], CUtil.Conversions.CultureAmerican));
                }
            }

            return listDoubles;
        }
        private static void AdaptQuartals_1(string inputHTML, IDataItem dataItem)
        {
            //1. extracts line containing quartals
            //string matchValue = @"<col align=..right..><col align=..right..><col align=..right..><tr class=..r1..><td style=..width:230px;text-align:left..> <.td><td style=..width:70px;text-align:right..>(?<1>.*?)<.td><.tr><tr class=..fh..><td style=..width:230px;text-align:left..>Period End Date";
            //string matchValue = @";text-align:right.(?<1>.*?).td><.tr><tr class=.fh.><td style=.width:230px;text-align:left.>Period End Date";
            string matchValue = @";text-align:right.(?<1>.*?)<.tr><tr class=.fh.><td style=.width:230px;text-align:left.>Period End Date";

            string line = GetLineMatch(inputHTML, matchValue);
            
            
            //2. now get quartal dates
            //extracts quartals in the format: 2010 Q2
            //string matchLine = @">(?<1>.*?)<.td>";
            string matchLine = @">(?<1>.*?)<.td>";
            CreateQuartalInstances(line, dataItem);

            //3. Revenue etc.
            matchLine = @"Total Revenue(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listSales = ExtractListOfDoubles(line, dataItem);

            //
            matchLine = @"Income Before Tax(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listEBIT = ExtractListOfDoubles(line, dataItem);

            matchLine = @"Gross Profit(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listProfit = ExtractListOfDoubles(line, dataItem);


            matchLine = @"Net Income<(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> incomeNet = ExtractListOfDoubles(line, dataItem);
            
            //assign
            for (int i = 0; i < dataItem.FundamentalData_Quartals.Count; i++)
            {
                IFundamentalData fd = dataItem.FundamentalData_Quartals[i];
                fd.Sales = listSales[i];
                fd.IncomeNet = incomeNet[i];
                fd.EBIT = listEBIT[i];
            }


        }
        private static void AdaptQuartals_2(string inputHTML, IDataItem dataItem)
        {
            //1. extracts line containing quartals

            //Total Assets
            string matchLine = @"Total Assets(?<1>.*?)<tr class=";
            string line = GetLineMatch(inputHTML, matchLine);
            IList<double> listAssets = ExtractListOfDoubles(line, dataItem);


            //Total Liabilities
            matchLine = @"Total Liabilities(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listLiabilities = ExtractListOfDoubles(line, dataItem);

            //Total Equity
            matchLine = @"Total Equity<(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listEquity = ExtractListOfDoubles(line, dataItem);
            
            //Total Common Shares Outstanding
            matchLine = @"Total Common Shares Outstanding<(?<1>.*?)<tr class=";
            line = GetLineMatch(inputHTML, matchLine);
            IList<double> listShares = ExtractListOfDoubles(line, dataItem);

            //assign
            for (int i = 0; i < dataItem.FundamentalData_Quartals.Count; i++)
            {
                IFundamentalData fd = dataItem.FundamentalData_Quartals[i];
                fd.Assets = listAssets[i];
                fd.LiabilitiesAll = listLiabilities[i];
                //fd.BV = listEquity[i]; -> is calculated in this sheet, but is the difference of above values
                fd.NoShares = Convert.ToInt64(listShares[i] * 1000000);

            }


        }
        private static void AdaptQuartals_3(string inputHTML, IDataItem dataItem)
        {
            //1. extracts line containing quartals

            //Net Cash - Beginning Balance
            //string matchLine = @"Net Cash - Beginning Balance(?<1>.*?)<tr class=";
            string matchLine = @"Cash from Operating Activities(?<1>.*?)<tr class=";
            string line = GetLineMatch(inputHTML, matchLine);
            IList<double> listCashFlow = ExtractListOfDoubles(line, dataItem);


            //assign
            for (int i = 0; i < dataItem.FundamentalData_Quartals.Count; i++)
            {
                IFundamentalData fd = dataItem.FundamentalData_Quartals[i];
                fd.CashFlow = listCashFlow[i];
             
            }


        }
        public static bool GetQuartalsData(IDataItem dataItem)
        {
            try
            {
                string symbol; string region;
                CUtil.IOUtil.SplitSymbolAndRegion(dataItem.Symbol, out symbol, out region);


                string url = @"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=" + region + "%3a" + symbol + "&lstStatement=Income&stmtView=Qtr";
                //e.g. http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=DE%3aBAYN&lstStatement=Income&stmtView=Qtr
                String inputHTML = SocketDownload.GetInternetPage(url);
                inputHTML = WebDownload.ReplaceInvalidCharacters(inputHTML);

                AdaptQuartals_1(inputHTML, dataItem);

                //----------------------------------
                url = @"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=" + region + "%3a" + symbol + "&lstStatement=Balance&stmtView=Qtr";
                //e.g. http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=DE%3aBAYN&lstStatement=Balance&stmtView=Qtr
                inputHTML = SocketDownload.GetInternetPage(url);
                inputHTML = WebDownload.ReplaceInvalidCharacters(inputHTML);

                AdaptQuartals_2(inputHTML, dataItem);

                //----------------------------------------------------------
                url = @"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=DE" + region + "%3a" + symbol + "&lstStatement=CashFlow&stmtView=Qtr";
                //e.g.  http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=DE%3aBAYN&lstStatement=CashFlow&stmtView=Qtr
                inputHTML = SocketDownload.GetInternetPage(url);
                inputHTML = WebDownload.ReplaceInvalidCharacters(inputHTML);
                AdaptQuartals_3(inputHTML, dataItem);


                CreateFundamentalDataFromQuartals(dataItem);

                dataItem.Parent.Serialize();
                return true;

            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in GetQuartalsData for : " + dataItem.ID + "; Message is: " + err.Message);
                return false;
            }
            
        }
        private static bool CreateFundamentalDataFromQuartals(IDataItem dataItem)
        {
            try
            {
                if (dataItem.FundamentalData_Quartals.Count > 0)
                {
                    DateTime dt = new DateTime(dataItem.FundamentalData_Quartals[0].Date.Year, 12, 31);
                    //IFundamentalData fdQuartal = GetFundamentalDataInstance(dt, dataItem, dataItem.FundamentalData);
                    IFundamentalData fdQuartal = dataItem.FundamentalData_Quartals[0];
                    //IFundamentalData fdNew = new FundamentalData();

                    IFundamentalData fdNew = GetFundamentalDataInstance(dt, dataItem, dataItem.FundamentalData);

                    fdNew.Assets = fdQuartal.Assets;
                    fdNew.LiabilitiesAll = fdQuartal.LiabilitiesAll;
                    //to calculate BV - as difference of above
                    fdNew.CashFlow = fdQuartal.CashFlow * 4;
                    fdNew.Depreciations = fdQuartal.Depreciations * 4;
                    fdNew.Equity = fdQuartal.Equity;
                    fdNew.IncomeNet = fdQuartal.IncomeNet * 4;
                    
                    fdNew.Sales = fdQuartal.Sales * 4;
                    fdNew.EBIT = fdQuartal.EBIT * 4;
                    fdNew.NoShares = fdQuartal.NoShares;

                    //check if already there
                   



                    return true;

                }
                return false;

            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in CreateFundamentalDataFromQuartals: " + err.Message);
                return false;

            }
            

        }

     
	}
}
